package main

import "fmt"

type dog struct {
	name string
}

type man struct {
	name string
}

type animaler interface {
	SayHello() //这里没有func开头
}

type higherAnimaler interface {
	animaler
	Sing()
}

func (d *dog) SayHello() {
	fmt.Println(d.name, "say hello")
}

func (m *man) SayHello() {
	fmt.Println(m.name, "say hello")
}

func (m *man) Sing() {
	fmt.Println(m.name, " is singing")
}

func WhoSayHello(i animaler) {
	i.SayHello()
}

func main() { //接口的转换，父接口=子接口（可以把子接口赋值给父接口的）
	var i animaler
	var hi higherAnimaler

	man := &man{"Tom"}
	hi = man

	i = hi //父亲是可以包含儿子的，但是儿子不能包含父亲：hi=i
	i.SayHello()
}

func main03() { //接口的继承
	var i animaler
	//实例化狗和人
	dog := new(dog)
	dog.name = "dog"
	i = dog //狗只实现了动物接口，所以不会唱歌
	i.SayHello()

	//人实现了高等动物的接口，并且实现了接口里的方法，所以人就可以做搞等动物能做的事儿
	man := new(man)
	man.name = "man"

	var hi higherAnimaler
	hi = man
	hi.SayHello()
	hi.Sing()

}

func main02() { //接口的多态
	var i animaler
	//实例化狗和人
	dog := new(dog)
	dog.name = "dog"

	man := new(man)
	man.name = "man"

	//狗和人分别调用接口定义的方法
	i = dog
	WhoSayHello(i)

	i = man
	WhoSayHello(i)
}

func main01() { //接口实现
	var i animaler
	//实例化狗和人
	dog := new(dog)
	dog.name = "dog"

	man := new(man)
	man.name = "man"

	//狗和人分别调用接口定义的方法
	i = dog
	i.SayHello()

	i = man
	i.SayHello()
}
